package dao

import (
	"github.com/sirupsen/logrus"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"time"
)

var mysqlDb *gorm.DB

// ConnectDb 连接到数据库
func ConnectDb() {
	logrus.Info("连接数据库")
	dsn := "root:denglibin@tcp(192.168.56.101:3306)/go_web_demo?charset=utf8&parseTime=True&loc=Asia%2FShanghai"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		CreateBatchSize:        100, //指定批量插入时 批次大小
		Logger:                 logger.Default.LogMode(logger.Info),
		SkipDefaultTransaction: true, //对于写操作（创建、更新、删除），为了确保数据的完整性，GORM 会将它们封装在事务内运行。但这会降低性能，你可以在初始化时禁用这种方式
		PrepareStmt:            true, //执行任何 SQL 时都创建并缓存预编译语句，可以提高后续的调用速度
	})
	if err != nil {
		panic(err)
	}
	mysqlDb = db
	//连接池
	sqlDB, err := db.DB()

	// SetMaxIdleConns 设置空闲连接池中连接的最大数量
	sqlDB.SetMaxIdleConns(10)

	// SetMaxOpenConns 设置打开数据库连接的最大数量。
	sqlDB.SetMaxOpenConns(100)

	// SetConnMaxLifetime 设置了连接可复用的最大时间。
	sqlDB.SetConnMaxLifetime(time.Hour)
	logrus.Info("连接数据库成功")

}

func init() {
	ConnectDb()
}

// Create 创建记录
func Create(entity interface{}, table string) {
	result := mysqlDb.Table(table).Create(entity)
	if result.Error != nil {
		panic(result.Error)
	}
}

// CreateSelectColumn 只创建指定字段
func CreateSelectColumn(entity interface{}, table string) {
	result := mysqlDb.Table(table).Select("Id", "Username", "Password").Create(entity)
	if result.Error != nil {
		panic(result.Error)
	}
}

// CreateInBatch 批量创建
func CreateInBatch(slice interface{}, table string) {

	//每批次大小为100
	result := mysqlDb.Table(table).CreateInBatches(slice, 100)
	if result.Error != nil {
		panic(result.Error)
	}
}

// QueryById 根据id查询
func QueryById(ptr interface{}, id int64, table string) {
	result := mysqlDb.Table(table).Limit(1).Find(ptr, id)
	if result.Error != nil {
		panic(result.Error)
	}

}

// QueryByIds 根据多个id查询
func QueryByIds(emptySlicePtr interface{}, ids []int, table string) int64 {
	result := mysqlDb.Table(table).Find(emptySlicePtr, ids)
	if result.Error != nil {
		panic(result.Error)
	}
	return result.RowsAffected
}

// QueryAll 查询所有 返回总数
func QueryAll(emptySlicePtr interface{}, table string) int64 {
	result := mysqlDb.Table(table).Order("id asc").Find(emptySlicePtr)
	//SELECT * FROM `user` ORDER BY id asc
	if result.Error != nil {
		panic(result.Error)
	}
	return result.RowsAffected
}

// QueryPage 分页查询
func QueryPage(emptySlicePtr interface{}, page int, size int, table string) int64 {
	var total int64
	//构造查询条件
	db := mysqlDb.Table(table)
	//查询总数
	db.Count(&total)
	// 查分页数据
	result := db.Limit(size).
		Offset((page - 1) * size).
		Order("id asc").
		Find(emptySlicePtr)
	if result.Error != nil {
		panic(result.Error)
	}
	return total
}
